package com.topisv.tms.web;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.topisv.tms.entity.CustomerLead;
import com.topisv.tms.entity.ExpressBillManage;
import com.topisv.tms.entity.JSONParam;
import com.topisv.tms.service.CustomerLeadService;
import com.topisv.tms.service.ExpressBillManageService;
import com.topisv.tms.tools.DataTablesUtils;
import com.topisv.tms.utils.excel.ExcelImportUtil;
import com.topisv.tms.utils.lead.LeadUtil;
import com.topisv.tms.web.base.BaseDataTableController;

import net.sf.json.JSONObject;

/**
 * 快递单流量管理
 * 快单的导入和查询
 * @author LiBin
 *
 */
@Controller
@RequestMapping(value = "/v2/expressBillManage")
public class ExpressBillManageController  extends BaseDataTableController {
	private static final Logger log = LoggerFactory.getLogger(ExpressBillManageController.class);
	
	
	@Autowired
	private ExpressBillManageService expressBillManageService;
	@Autowired
	private ExcelImportUtil excelImportUtil;
	@Autowired
	private CustomerLeadService customerLeadService;
	
	/**
	 * 返回list<string>集合
	 * @param mList
	 * @return
	 */
	public List<String> getListString(List<Map<String, Object>> mList) {
		List<String> customerNameList=new ArrayList<String>();
		for (Map<String, Object> item : mList) {
			Iterator<String> it = item.keySet().iterator();  
		       while (it.hasNext()) {  
		           String key = it.next().toString();  
		           customerNameList.add((String) item.get(key));  
		       }  
		}
		
	 return	customerNameList;
	}
	
	/**
	 * 导向快递单查询页面
	 * @return
	 */
	@RequestMapping(value = "init")
	public String init(ServletRequest request,HttpServletResponse response,Model model) {
		
		List<Map<String, Object>> tempCustomerNameList=expressBillManageService.findCustomerNames();
		List<Map<String, Object>> tempToProvinceList=expressBillManageService.findToProvinces();
		model.addAttribute("customerNameList",getListString(tempCustomerNameList));//getListString(tempCustomerNameList)
		model.addAttribute("toProvinceList",getListString(tempToProvinceList));
		
		return "expressBill/expressBillList";
	}
	
	/**
	 * 查询数据
	 * @param paramJson
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	 @RequestMapping(value="/loadData", method=RequestMethod.POST) 
     public void loadData(@RequestBody JSONParam[] paramJson,HttpServletRequest request, HttpServletResponse response) throws Exception {
		try {
			//变量定义
			PrintWriter out=response.getWriter();
			JSONObject json=new JSONObject();
			Page<ExpressBillManage> page=null;
			Map<String, Object> param=new HashMap<String, Object>();
            //ShiroUser shiroUser = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
			
			//客户端参数
			Map<String, String> paramMap = DataTablesUtils.convertToMap(paramJson);
			String sEcho = paramMap.get("sEcho");  
			int start = Integer.parseInt(paramMap.get("iDisplayStart"));
			int length = Integer.parseInt(paramMap.get("iDisplayLength")); 
            param.put("customerName", paramMap.get("customerName"));
            param.put("expressNo", paramMap.get("expressNo"));
            param.put("orderNo", paramMap.get("orderNo"));
            param.put("toProvince", paramMap.get("toProvince"));
            param.put("toName", paramMap.get("toName"));
            param.put("fromDate", paramMap.get("fromDate"));
            param.put("toDate", paramMap.get("toDate"));

			//查询
			int curPage=(start/length)+1;
			page = expressBillManageService.loadPageExpressBill(param,curPage, length);
	        List<ExpressBillManage> eOrderList=page.getContent();
	        
	        //封装查询结果
	        json.put("aaData", eOrderList);
	        json.put("sEcho", sEcho);
	        json.put("iTotalRecords", page.getTotalElements());
	        json.put("iTotalDisplayRecords", page.getTotalElements());
	        
	        out.print(json);
        
		} catch (Exception e) {
			log.error("搜索查询异常", e);
		}
    } 
	
	 /**
	  * 运单详情
	  * @param request
	  * @param response
	  * @throws Exception
	  */
	 @RequestMapping(value="/ajaxBillDetail", method=RequestMethod.POST) 
     public void ajaxBillDetail(HttpServletRequest request, HttpServletResponse response) {
		PrintWriter out=null;
		JSONObject json=new JSONObject();
		try {
			//变量定义
			out=response.getWriter();
			String id=request.getParameter("id");
			
			ExpressBillManage expressBillManage=expressBillManageService.findOne(Long.parseLong(id));
			json.put("status", "1");//成功
	        json.put("expressBillManage", expressBillManage);
	        out.print(json);
		} catch (Exception e) {
			json.put("status", "0");
	        out.print(json);
		}
    }
	 
	//TODO 之后完成工具
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "expressImport",method = RequestMethod.GET)
	public String expressImport(@PathVariable(value="customerCode") String customerCode,Model model,ServletRequest request){
		HttpServletRequest httpRequest = null;
		DiskFileItemFactory factory = null;
		ServletFileUpload upload = null;
		List<FileItem> items = null;
		
		try {
			httpRequest = (HttpServletRequest) request;
			httpRequest.setCharacterEncoding("UTF-8");
			factory = new DiskFileItemFactory();
			upload = new ServletFileUpload(factory);
			items = upload.parseRequest(httpRequest);
			
			excelImportUtil.excelToEntity(items, new ExpressBillManage());
			
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (FileUploadException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return "";
		
	}
	
	/**
	 * 检查是否有快递单流量导入模板
	 * @param erpType
	 * @param customers
	 * @param response
	 */
	@RequestMapping(value="/ajaxCheckExpressModel", method = RequestMethod.POST)
	public void ajaxCheckExpressModel(HttpServletRequest request, HttpServletResponse response) {
		
		PrintWriter out=null;
		JSONObject json=null;
		try {
			json=new JSONObject();
			out=response.getWriter();
			String customers=request.getParameter("customers");
			String erpType=request.getParameter("erpType");
			CustomerLead customerLead=this.customerLeadService.findByCustomerCodeAndOrdenoSource(customers, erpType);
			if (null!=customerLead && !customerLead.getCustomerCode().isEmpty()) {
				json.put("status", "1");//已经设置过模板
			}else {
				json.put("status", "2");//没有模板
			}
			out.print(json.toString());
		} catch (Exception e) {
			json.put("status", "0");
			out.print(json.toString());
			log.error("查询模板异常", e);
		}
	}
	
	/**
	 * 获取模板的标题行，用于设置和表的对应关系
	 * @param customerCode
	 * @param type
	 * @param model
	 * @param request
	 * @param redirectAttributes
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "getExcelTop/{customerCode}/{type}")
	public String getExcelTop(
			@PathVariable(value = "customerCode") String customerCode,
			@PathVariable(value = "type") String type, Model model,
			ServletRequest request, RedirectAttributes redirectAttributes) {
		HttpServletRequest httpRequest = null;
		DiskFileItemFactory factory = null;
		ServletFileUpload upload = null;
		List<FileItem> items = null;
		List<String> sequence = null;
		try {
			log.info("快递模板设置开始getExcelTop");
			httpRequest = (HttpServletRequest) request;
			httpRequest.setCharacterEncoding("UTF-8");
			factory = new DiskFileItemFactory();
			upload = new ServletFileUpload(factory);

			items = upload.parseRequest(httpRequest);
			Iterator<FileItem> itr = items.iterator();
			while (itr.hasNext()) {
				FileItem item = (FileItem) itr.next();
				if (!item.isFormField() && item.getName() != null
						&& !item.getName().equals("")) {
					// 获取Excel文件对象
					InputStream stream = item.getInputStream();
					sequence = analyseExcelToString(stream, item.getName());
				}
			}
			model.addAttribute("keys", sequence);
			model.addAttribute("customerCode", customerCode);
			model.addAttribute("type", type);
		} catch (Exception e) {
			model.addAttribute("message", "读取模板数据失败！");
			log.info("导入失败getExcelTop");
		}

		return "expressBill/setExpressExcelMould";
	}
	
	/**
	 * 解析excel，返回string的集合
	 * @param excelName 
	 * @param stream
	 * @return
	 * @throws IOException
	 */
	private List<String> analyseExcelToString(InputStream stream,String excelName) throws IOException {
		List<String> sequence=null;
		Workbook rwb=getWorkbook(stream,excelName);
		if(null==rwb) return null;
		if(rwb.getNumberOfSheets()>0){
			sequence=LeadUtil.getTopNew(rwb.getSheetAt(0));
		}
		return sequence;
	}
	/**
	 * 解析excel，返回ExpressBillManage的集合
	 * @param excelName 
	 * @param stream
	 * @return
	 * @throws IOException
	 */
	private List<ExpressBillManage> analyseExcelToExpressBillManage(InputStream stream,String excelName,CustomerLead customerLead
			,String customerCode) throws IOException {
		List<ExpressBillManage> expressBillManages = new ArrayList<ExpressBillManage>();
		Workbook rwb=getWorkbook(stream,excelName);
		if(null==rwb) return null;
		for (int i = 0; i < rwb.getNumberOfSheets(); i++) {
			Sheet sheet = rwb.getSheetAt(i);
			int rows=sheet.getLastRowNum();
			if(rows>0){
				expressBillManages.addAll(LeadUtil.getExpressBillManage(customerLead,customerCode,sheet));
			}
		}
		return expressBillManages;
	}
	/**
	 * 根据excel版本初始化 Workbook 对象
	 * @param stream 待转化的流
	 * @param excelName 
	 * @return Workbook对象
	 * @throws IOException
	 */
	private Workbook getWorkbook(InputStream stream,String excelName) throws IOException {
		Workbook rwb = null;
		if(excelName.endsWith(".xls")){
			rwb = new HSSFWorkbook(stream);
		}else if (excelName.endsWith(".xlsx")) {
			rwb = new XSSFWorkbook(stream);
		}else {
			return null;
		}
		return rwb;
	}
	
	/**
	 * 开始导入快递单信息
	 * @param customerCode
	 * @param model
	 * @param request
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "leadExpressBillManage/{customerCode}/{updateType}")
	public String leadExpressBillManage(@PathVariable(value = "customerCode") String customerCode,@PathVariable(value = "updateType") String updateType,@RequestParam(value = "overWrite",required=false) Boolean overWrite,Model model,
			ServletRequest request, RedirectAttributes redirectAttributes) {
		HttpServletRequest httpRequest = null;
		DiskFileItemFactory factory = null;
		ServletFileUpload upload = null;
		List<FileItem> items = null;
		InputStream stream = null;
		if(null == overWrite)overWrite = Boolean.FALSE;
		try {
			httpRequest = (HttpServletRequest) request;
			httpRequest.setCharacterEncoding("UTF-8");
			factory = new DiskFileItemFactory();
			upload = new ServletFileUpload(factory);
			items = upload.parseRequest(httpRequest);
			Iterator<FileItem> itr = items.iterator();
			log.info("leadExpressBillManage---开始导入");
			CustomerLead customerLead=this.customerLeadService.findByCustomerCodeAndOrdenoSource(customerCode, updateType);
			while (itr.hasNext()) {
				FileItem item = (FileItem) itr.next();
				if (!item.isFormField()) {
					if (item.getName() != null && !item.getName().equals("")) {
						List<ExpressBillManage> expressBillManages = new ArrayList<ExpressBillManage>();
						// 获取Excel文件对象
						stream = item.getInputStream();
						expressBillManages=analyseExcelToExpressBillManage(stream,item.getName(),customerLead,customerCode);
						//Map<String, List<ExpressBillManage>> maps=expressBillManageService.save(customerCode,expressBillManages,overWrite);
						if(expressBillManages.size()<1){
							model.addAttribute("message", "模板异常或者模板数据不对应！");
							return "expressBill/result";
						}
						
						int m=expressBillManageService.deleteByexpress(expressBillManages);
						int []n=expressBillManageService.sava(customerCode, expressBillManages, overWrite);
						model.addAttribute("normalSize", n.length);
						model.addAttribute("exceptionSize", expressBillManages.size()-n.length);
						model.addAttribute("repeatSize", m);
						model.addAttribute("message", "success");
					} else {
						model.addAttribute("message", "请提供快递流量数据文件");
					}
				}
			}
		} catch (Exception e) {
			log.error("leadExpressBillManage--Error.",e);
			model.addAttribute("message", "服务器异常，导入数据失败，如果重试还是这样请联系开发技术支持");
		} finally {
			if (null != stream) {
				try {
					stream.close();
				} catch (IOException e) {
					log.info("leadExpressBillManage--out of memory");
				}
			}
		}
		return "expressBill/result";
	}
	
	
	/**
	 * 设置快递流量导入模板 
	 * @param customerCode STO 表示快递流量导入模板
	 * @param params
	 * @param type  setExpressBillMould
	 * @param response
	 */
	@RequestMapping(value = "ajaxLeadExpressBillMould")
	public void ajaxLeadExpressBillMould(
			@RequestParam(value = "customerCode") String customerCode,
			@RequestParam(value = "params") String params,
			@RequestParam(value = "type") String type,
			HttpServletResponse response) {
		JSONObject json = new JSONObject();
		PrintWriter out = null;
		try {
			out = response.getWriter();
			CustomerLead customerLead = this.customerLeadService
					.findByCustomerCodeAndOrdenoSource(customerCode, type);
			if (customerLead == null) {
				customerLead = new CustomerLead();
				customerLead.setCustomerCode(customerCode);
				customerLead.setOrdenoSource(type);
				customerLead.setStatus("pending");
				customerLead.setCreateTime(new Date());
			}
			customerLead.setParams(params);
			this.customerLeadService.save(customerLead);
			log.info(customerCode + "快递流量导入模板 成功");
			json.put("content", "设置成功");
			json.put("status", "1");
			out.print(json.toString());

		} catch (Exception e) {
			json.put("status", "0");
			json.put("content", e.getMessage());
			if (null != out)
				out.print(json.toString());
			log.error(customerCode + "快递流量导入模板异常 ", e);
		}
	}
	
}
